// 放大镜构造函数
// 参数1    生成放大镜内容的标签对象
// 参数2    放大镜参数数据数组
class setGlass{
    constructor(element , array){
        // 定义属性存储参数
        this.ele = element ;
        this.arr = array ;
        // 定义属性存储数据
        this.show ;
        this.img ;
        this.mask ;
        this.list ;
        this.listLiImg ;
        this.glass ;
    }

    // 入口函数
    init(){
        // 入口函数中调用所有需要执行的函数程序
        this.setPage() ;
        this.setMouseOver();
        this.setMouseMove();
    }

    // 动态生成页面
    setPage(){
        // 创建标签对象
        this.show = document.createElement('div');
        this.mask = document.createElement('div');
        this.glass = document.createElement('div');
        this.img = document.createElement('img');
        this.list = document.createElement('ul');

        // 设定标签对象的相关属性

        // 显示区 设定 class选择器
        this.show.classList.add('show');
        this.mask.classList.add('mask');
        this.list.classList.add('list');
        this.glass.classList.add('glass');

        // 图片标签 默认显示 数组中 第一组数据中 large图片
        this.img.setAttribute( 'src' , `./images/${this.arr[0].large}` );
        // 图片标签 添加name属性值
        this.img.setAttribute( 'name' , 'showImg');
        this.mask.setAttribute( 'name' , 'showImg');


        // 显示区中 有 图片标签 和 遮盖层标签
        this.show.appendChild( this.img );
        this.show.appendChild( this.mask );

        // 给 this.show  这个节点 直接 绑定事件
        // 绑定好事件之后 再 执行写入操作
        // 之后 即使 再次动态渲染生成页面 也是 创建新的this.show节点 同时绑定事件 再写入节点
        this.show.addEventListener('mouseenter' , ()=>{
            // 移入 让 遮盖层 和 放大镜 显示
            this.mask.style.display = 'block';
            this.glass.style.display = 'block';
        })

        this.show.addEventListener('mouseleave' , ()=>{
            // 移入 让 遮盖层 和 放大镜 隐藏
            this.mask.style.display = 'none';
            this.glass.style.display = 'none';
        })

        // 给 显示区 div标签 添加 鼠标移入事件
        // this.show.addEventListener('mousemove' , ()=>{
        //     console.log(111);
        // })

        // 根据数组生成 list 中 li 标签对象
        let liStr = '' ;

        this.arr.forEach( (item , key) => {
            liStr += key === 0 ? `<li><img name="liImg" class="active" index="${key}" src="./images/${item.small}" alt=""></li>` : `<li><img name="liImg" index="${key}" src="./images/${item.small}" alt=""></li>` 
        })

        // 将 字符串 写入 list,ul标签中
        this.list.innerHTML = liStr ;

        // 将 标签对象 写入 box,div标签 中
        this.ele.appendChild( this.show );
        this.ele.appendChild( this.list );
        this.ele.appendChild( this.glass );

        // 将 标签对象 写入 box,div标签 之后 
        // 获取 list 标签中的 li标签 中的 img标签
        this.listLiImg = this.list.querySelectorAll('li>img');

    }

    // 鼠标 移入 图片
    // 只有 移入没有移出 可以 事件委托添加给 图片标签
    setMouseOver(){
        // 给 父级div标签 添加 鼠标移入事件
        this.ele.addEventListener('mouseover' , e => {
            // 如果 移入的标签 name 是 liImg 证明 移入的是 列表 图片标签
            if(e.target.getAttribute('name') === 'liImg'){
                // 1 清除其他的img标签 class,active 给 移入的img标签添加 class,active
                // 循环遍历 所有的 li>img 清除 class,active
                this.listLiImg.forEach( item => {
                    // item 就是 图片标签对象
                    item.classList.remove('active');
                })
                // 给经过的 li>img 添加 class,active
                e.target.classList.add('active');

                // 2 设定 show显示区域中img标签src属性 
                // 是 鼠标进过的 li>img 标签 index属性中 存储的索引下标
                this.img.setAttribute( 'src' , `./images/${this.arr[ Number( e.target.getAttribute('index') ) ].large}` );

                // 3 设定 glass放大镜中背景图片的css样式
                this.glass.style.backgroundImage = `url('./images/${this.arr[ Number( e.target.getAttribute('index') ) ].large}')`;
                
            }
        })
    }

    // 鼠标 拖住效果
    setMouseMove(){
        // 获取 数据 

        // 获取 box,div的 外间距
        let oBoxLeft = this.ele.offsetLeft ;
        let oBoxTop = this.ele.offsetTop ;

        // 获取 show,div的 边框线
        let oShowBorderLeft = this.show.clientLeft ;
        let oShowBorderTop = this.show.clientTop ;

        // 获取 show,div的 占位 内容+padding
        let oShowWidth = this.show.clientWidth ; 
        let oShowHeight = this.show.clientHeight ; 

        // 获取 mask,div的 占位 内容+padding+border
        let oMaskWidth = parseInt( window.getComputedStyle( this.mask ).width ); 
        let oMaskHeight = parseInt( window.getComputedStyle( this.mask ).height ); 

        // 给 父级div标签 添加 鼠标移动事件
        // 如果 是 在 show,div 中 img标签 触发移动事件 执行 鼠标拖拽效果
        this.ele.addEventListener( 'mousemove' , e => {
            // 事件对象标签 name 是 showImg 证明 触发的标签是 show,div中的img标签
            if( e.target.getAttribute('name') === 'showImg' ){
                // 1, 计算设定 遮盖层定位数据
                let x = e.pageX - oBoxLeft - oShowBorderLeft - oMaskWidth/2 ;
                let y = e.pageY - oBoxTop - oShowBorderTop - oMaskHeight/2 ;

                // 2, 设定极值
                x = x < 0 ? 0 : x ;
                y = y < 0 ? 0 : y ;

                x = x > oShowWidth - oMaskWidth ? oShowWidth - oMaskWidth : x ;
                y = y > oShowHeight - oMaskHeight ? oShowHeight - oMaskHeight : y ;

                // 3, 将 遮盖层定位赋值
                this.mask.style.left = x + 'px';
                this.mask.style.top = y + 'px';

                // 4, 设定 背景图片定位数值 
                // 和 遮盖层定位数值方向相反 比例关系 是 4倍
                this.glass.style.backgroundPosition = `${-x*4}px ${-y*4}px` ;
            }
        })

    }



    // 鼠标的移入移出
    // 不能给父级添加标签 通过 事件委托 给 子级标签 执行 移入移出
    // 子级标签 触发 over移入的同时 也会触发 out移出 事件

    // setMouse(){
    //     // 鼠标移入box,div 事件委托 show,div
    //     this.ele.addEventListener( 'mouseover' , e=>{
    //         // 如果 移入 标签,class选择器是 show 移入的是 show,div标签
    //         if( e.target.className === 'show' ){
    //             console.log(111);
    //             // // 让 遮盖层 和 放大镜 显示
    //             // this.mask.style.display = 'block';
    //             // this.glass.style.display = 'block';
    //         }
    //     })

    //     // 鼠标移入box,div 事件委托 show,div
    //     this.ele.addEventListener( 'mouseout' , e=>{
    //         // 如果 移出 标签,class选择器是 show 移入的是 show,div标签
    //         if( e.target.className === 'show' ){
    //             console.log(222);
    //             // // 让 遮盖层 和 放大镜 隐藏消失
    //             // this.mask.style.display = 'none';
    //             // this.glass.style.display = 'none';
    //         }
    //     })
    // }
}